package com.university.report.user.config;

import com.university.report.common.utils.MD5Util;
import com.university.report.model.entity.Permission;
import com.university.report.user.filter.JWTLoginFilter;
import com.university.report.user.filter.JWTValidationFilter;
import com.university.report.user.filter.JwtAuthenticationTokenFilter;
import com.university.report.user.handler.MyLogoutHandler;
import com.university.report.user.handler.MyLogoutSuccessHandler;
import com.university.report.user.mapper.PermissionMapper;
import com.university.report.user.service.impl.MemberUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @ClassName health_report
 * @Author Jinondo
 * @Date 2021/6/16 18:04
 */
@Component
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {


    @Autowired
    private RedisTemplate redisTemplate2;

    @Autowired
    private MemberUserDetailsService memberUserDetailsService;
    @Autowired
    private PermissionMapper permissionMapper;

    /**
     * 注销操作处理器
     */
    @Autowired
    private MyLogoutHandler myLogoutHandler;

    /**
     * 注销成功处理器
     */
    @Autowired
    private MyLogoutSuccessHandler myLogoutSuccessHandler;

    @Autowired
    JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
//    @Autowired
//    JWTValidationFilter jwtValidationFilter;
    /**
     * 添加授权账户
     *
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth.userDetailsService(memberUserDetailsService).passwordEncoder(new PasswordEncoder() {

            @Override
            public String encode(CharSequence rawPassword) {
                return MD5Util.encode((String) rawPassword);
            }

            /**
             * rawPassword 用户输入的密码
             * encodedPassword 数据库DB的密码
             * @param rawPassword
             * @param encodedPassword
             * @return
             */
            @Override
            public boolean matches(CharSequence rawPassword, String encodedPassword) {
                String rawPass = MD5Util.encode((String) rawPassword);
                boolean result = rawPass.equals(encodedPassword);
                return result;
            }
        });
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.addFilterAt(new JWTLoginFilter(authenticationManager(),redisTemplate2),UsernamePasswordAuthenticationFilter.class)
//        .addFilterAfter(jwtAuthenticationTokenFilter, JWTLoginFilter.class);
//            .addFilterAfter(jwtValidationFilter,JWTLoginFilter.class);

        .addFilterAfter(new JWTValidationFilter(authenticationManager(),redisTemplate2),JWTLoginFilter.class);

        List<Permission> allPermission = permissionMapper.selectList(null);
        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry
                expressionInterceptUrlRegistry = http.authorizeRequests();
        allPermission.forEach((permission) -> {
            expressionInterceptUrlRegistry.antMatchers(permission.getUrl()).
                    hasAnyAuthority(permission.getPermTag());

        });
        expressionInterceptUrlRegistry
                .antMatchers("/auth/login").permitAll()
                .antMatchers("/login/**").permitAll()
                .antMatchers("/api/exportUnReported").permitAll()
                .antMatchers("/api/exportUser").permitAll()
                .antMatchers("/**").fullyAuthenticated()
                .and()
                .logout().permitAll()
                .addLogoutHandler(myLogoutHandler)
                .logoutSuccessHandler(myLogoutSuccessHandler)
                //登出之后删除 cookie
                .deleteCookies("JSESSIONID")
                .and()
                .csrf().disable()
                // 剔除 session
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        //放行swagger
        web.ignoring().antMatchers(HttpMethod.GET,
                "/v2/api-docs",
                "/swagger-resources",
                "/swagger-resources/**",
                "/configuration/ui",
                "/configuration/security",
                "/swagger-ui.html/**",
                "/webjars/**");
    }

}
